import { ifs, ts, Tsrv } from '@/services';
import axios from 'axios';
import { N_cAutoDataQuery } from './type';

class T_cmd {
  // 主组件实例
  private self: N_cAutoDataQuery.cAutoDataQuery;

  // 主组件created里初始化
  public init(self: N_cAutoDataQuery.cAutoDataQuery) {
    this.self = self;
  }

  // 格式化日期
  public formatDate(date: Date, isEnd = false): string {
    const day = isEnd
      ? (date.getDate() + 1).toString().padStart(2, '0')
      : date.getDate().toString();
    return `${date.getFullYear()}-${(date.getMonth() + 1)
      .toString()
      .padStart(2, '0')}-${day}`;
  }

  // 计算工作日数（简单自然日计算）
  public calculateWorkDays(start: Date, end: Date): number {
    const diffTime = end.getTime() - start.getTime();
    return Math.ceil(diffTime / (1000 * 60 * 60 * 24)) + 1;
  }

  // 初始化返回数据结构
  private initReturnData(
    params: N_cAutoDataQuery.QueryParams
  ): N_cAutoDataQuery.TableDataItem {
    const { dateRange, workDays } = params;
    return {
      execTime: null,
      totalWorkTime: workDays * 24,
      utilization: null,
      autoOrders: null,
      autoRacks: null,
      totalOrders: null,
      totalracks: null,
      autoRate: null,
      autoRackRate: null,
      evalPeriod: `${this.formatDate(dateRange[0])}~${this.formatDate(
        dateRange[1]
      )}`
    };
  }

  // 查询生产数据
  private async queryProductionData(
    tableName: string,
    dateRange: [Date, Date]
  ): Promise<any[]> {
    const Tfilter = new ts.T_filter();
    const gteCondition = Tfilter.parseGTE(
      'create_time',
      this.formatDate(dateRange[0])
    );
    const lteCondition = Tfilter.parseLTE(
      'create_time',
      this.formatDate(dateRange[1], true)
    );
    // const eqCondition = Tfilter.parseEQ('is_automated_produc', 1);
    const filter = Tfilter.parseAND([gteCondition, lteCondition]);

    const [b, res, rows, err] = await this.doLoadData(tableName, filter);
    if (!b) {
      this.self.$msg(err);
      return [];
    }
    return rows;
  }

  // 查询订单数据
  private async queryOrderData(
    tableName: string,
    filter: object
  ): Promise<any[]> {
    const [b, res, rows, err] = await this.doLoadData(tableName, filter);
    if (!b) {
      this.self.$msg(err);
      return [];
    }
    return rows;
  }

  // 计算统计数据
  private calculateStats(
    productionRows: any[],
    orderRows: any[],
    totalWorkTime: number
  ) {
    const totalExecTime = productionRows.reduce(
      (prev, item) => prev + item.unit_order_execution_time,
      0
    );

    const autoOrders = this.countOrdersByCategory(orderRows);
    const totalAutoOrders = Object.values(autoOrders).reduce(
      (prev: number, item: number) => prev + item,
      0
    );

    return {
      execTime: totalExecTime,
      utilization: `${((totalExecTime / totalWorkTime) * 100).toFixed(2)}%`,
      autoOrders: totalAutoOrders
    };
  }

  // 按category统计订单数(处理自动化订单覆盖逻辑)
  private countOrdersByCategory(
    autoRows: any[],
    allRows: any[] = []
  ): { [key: string]: number } {
    const orderMap = new Map<string, any>();

    // 处理所有订单(hang_group_detail_mamt)
    allRows.forEach(item => {
      const existing = orderMap.get(item.category_number);
      const isAutomated = item.is_automated_produc === 1;
      if (
        !existing ||
        new Date(item.create_time) > new Date(existing.create_time)
      ) {
        orderMap.set(item.category_number, {
          ...item,
          isAutomated
        });
      }
    });

    // 处理自动化订单(hang_group_detail_mamt)
    autoRows.forEach(item => {
      const existing = orderMap.get(item.category_number);
      if (
        !existing ||
        new Date(item.create_time) > new Date(existing.create_time)
      ) {
        orderMap.set(item.category_number, {
          ...item,
          isAutomated: true
        });
      }
    });

    // 统计自动化订单数
    const result: { [key: string]: number } = {};
    orderMap.forEach(item => {
      if (item.isAutomated) {
        result[item.category_number] = (result[item.category_number] || 0) + 1;
      }
    });

    return result;
  }

  // 生成表格数据
  public async generateTableData(
    params: N_cAutoDataQuery.QueryParams
  ): Promise<N_cAutoDataQuery.TableDataItem[]> {
    const returnData = this.initReturnData(params);
    const { dateRange } = params;

    try {
      // 查询生产数据
      const totalProductionRows = await this.queryProductionData(
        'produc_line_detail_mgmt',
        dateRange
      );
      if (totalProductionRows.length === 0) return [returnData];

      // 计算自动化挂组数与总挂组数
      const autoProductionRows = totalProductionRows.filter(
        item => item.is_automated_produc
      );
      returnData.autoRacks = autoProductionRows.length;
      returnData.totalracks = totalProductionRows.length;
      returnData.autoRackRate = `${(
        (returnData.autoRacks / returnData.totalracks) *
        100
      ).toFixed(2)}%`;

      // 计算执行时间和利用率
      const stats = this.calculateStats(
        autoProductionRows,
        [],
        returnData.totalWorkTime
      );
      returnData.execTime = Math.round(stats.execTime * 100) / 100;
      returnData.utilization = stats.utilization;

      // 查询订单数据
      const Tfilter = new ts.T_filter();
      const ids = autoProductionRows.map(item => item.id);
      const inCondition = Tfilter.parseIN('master_bill_id', ids);

      const [autoOrderRows, totalOrderRows] = await Promise.all([
        this.queryOrderData('hang_group_detail_mamt', inCondition),
        this.queryOrderData(
          'hang_group_detail_mamt',
          Tfilter.parseAND([
            Tfilter.parseGTE('create_time', this.formatDate(dateRange[0])),
            Tfilter.parseLTE('create_time', this.formatDate(dateRange[1], true))
          ])
        )
      ]);

      // 计算订单统计数据
      const autoOrders = this.countOrdersByCategory(
        autoOrderRows,
        totalOrderRows
      );
      const totalOrders = this.countOrdersByCategory(totalOrderRows);

      returnData.autoOrders = Object.values(autoOrders).reduce(
        (prev: number, item: number) => prev + item,
        0
      );
      returnData.totalOrders = Object.values(totalOrders).reduce(
        (prev: number, item: number) => prev + item,
        0
      );
      returnData.autoRate = `${(
        (returnData.autoOrders / returnData.totalOrders) *
        100
      ).toFixed(2)}%`;
    } catch (error) {
      this.self.$msg(error.message);
    }

    return [returnData];
  }

  public doLoadData(tableName: string, filter = {}) {
    const gpd = new ts.T_getPartDataArg();
    gpd.setFilter(filter);
    gpd.setFunName(tableName);
    gpd.setTableName(tableName);
    gpd.setDbType(Tsrv.globalVar.dbType.MYSQL);
    gpd.setLang(this.self.$i18n.locale);
    gpd.setPage(1, 99999);
    gpd.setRule({} as ifs.I_rule);

    return Tsrv.getData(gpd);
  }

  // 验证工作日数
  public validateWorkDays(workDays: number, dateRange: [Date, Date]): boolean {
    const days = this.calculateWorkDays(dateRange[0], dateRange[1]);
    return workDays <= days;
  }

  // 上传数据到外部系统
  public async uploadData(
    tableData: N_cAutoDataQuery.TableDataItem[],
    queryParams: N_cAutoDataQuery.QueryParams
  ): Promise<{ success: boolean; message: string }> {
    try {
      // 1. 检查是否已上传过相同时间段数据
      const isUploaded = await this.checkUploadHistory(queryParams.dateRange);
      if (isUploaded) {
        throw new Error('该时间段数据已上传过，请勿重复上传');
      }

      // 2. 准备上传数据
      const postData = {
        deviceId: '大件氧化线',
        upstring: this.formatDateRange(queryParams.dateRange),
        autoWorkTime: tableData[0].totalWorkTime,
        autoProductTime: tableData[0].execTime,
        utilization: tableData[0].utilization,
        autoOrders: tableData[0].autoOrders,
        totalOrders: tableData[0].totalOrders,
        autoRate: tableData[0].autoRate,
        autoRacks: tableData[0].autoRacks,
        totalracks: tableData[0].totalracks,
        autoRackRate: tableData[0].autoRackRate
      };

      // 3. 发送POST请求
      const response = await axios.post('kpi-data-out', postData);

      // 4. 返回成功结果
      return {
        success: true,
        message: '上传成功'
      };
    } catch (error) {
      return {
        success: false,
        message: error.message || '上传失败'
      };
    }
  }

  private async checkUploadHistory(date: [Date, Date]) {
    const [b, res, rows, err] = await this.doLoadData(
      'auto_data_upload_record',
      {}
    );
    let isUploaded = false;
    if (!b) {
      this.self.$msg(err);
    } else {
      // upload_date
      const dates = rows.map(it => it['upload_date']);
      for (const el of dates) {
        const startDate = el.split('~')[0];
        const endDate = el.split('~')[1];
        if (
          new Date(date[0]).getTime() < new Date(endDate).getTime() &&
          new Date(date[1]).getTime() > new Date(startDate).getTime()
        ) {
          isUploaded = true;
          break;
        }
      }
    }
    return isUploaded;
  }

  // 格式化日期范围
  private formatDateRange(dateRange: [Date, Date]): string {
    return `${this.formatDate(dateRange[0])}~${this.formatDate(dateRange[1])}`;
  }
}

interface I_cmd extends T_cmd {}

export { I_cmd, T_cmd };
